package top.zhi.utils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
/**
 * 数据辅助类 * 
 * @author zhi
 */
public class Verification {
	//统一社会信用代码正则
	private final static String CONPANY_CODE_PATTERN = "^[0-9A-HJ-NP-RTUWXY]{18}$"; 
	//统一社会信用代码各位字符对应数字的权重
	private final static int[] COMPANY_WEIGHT = {1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28};
	//统一社会信用代码字符对应的数字
	private final static HashMap<String,Integer> COMPANY_CHAR_WEIGHT = new HashMap<String,Integer>() {
		{
			put("0",0);
			put("1",1);
			put("2",2);
			put("3",3);
			put("4",4);
			put("5",5);
			put("6",6);
			put("7",7);
			put("8",8);
			put("9",9);
			put("A",10);
			put("B",11);
			put("C",12);
			put("D",13);
			put("E",14);
			put("F",15);
			put("G",16);
			put("H",17);
			put("J",18);
			put("K",19);
			put("L",20);
			put("M",21);
			put("N",22);
			put("P",23);
			put("Q",24);
			put("R",25);
			put("T",26);
			put("U",27);
			put("W",28);
			put("X",29);
			put("Y",30);
		}
	};
	//身份证正则
	private final static String IDCARD_PATTERN = "^\\d{17}[\\d|X]$";
	//身份证号码各位字符对应数字的权重
	private final static int[] IDCARD_WEIGHT = {7 ,9 ,10 ,5 ,8 ,4 ,2 ,1 ,6 ,3 ,7 ,9 ,10 ,5 ,8 ,4 ,2};
	//身份证各位加权对11取余后最后一位的对应字符
	private final static String[] IDCARD_CHECK_CODE = {"1","0","X","9","8","7","6","5","4","3","2"};
	//车牌号正则
	private final static String REGNO_PATTERN = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4,5}[A-Z0-9挂学警港澳]{1}$";
	//VIN正则，VIN是17位数字和大写字母组成的(不包含IOQ，第10位不能是IOQUZ0)
	private final static String VIN_PATTERN = "^[0-9A-HJ-NPR-Z]{9}[1-9A-HJ-NPR-TV-Y][0-9A-HJ-NPR-Z]{7}$";
	//VIN位数权重
	private final static int[] VIN_WEIGHT={8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2};
	//VIN字母数字对照表
	private final static HashMap<String,Integer> VIN_CHAR_WEIGHT = new HashMap<String,Integer>() {
		{
			put("0",0);
			put("1",1);
			put("2",2);
			put("3",3);
			put("4",4);
			put("5",5);
			put("6",6);
			put("7",7);
			put("8",8);
			put("9",9);
			put("A",1);
			put("B",2);
			put("C",3);
			put("D",4);
			put("E",5);
			put("F",6);
			put("G",7);
			put("H",8);
			put("J",1);
			put("K",2);
			put("L",3);
			put("M",4);
			put("N",5);
			put("P",7);
			put("R",9);
			put("S",2);
			put("T",3);
			put("U",4);
			put("V",5);
			put("W",6);
			put("X",7);
			put("Y",8);
			put("Z",9);
		}
	};
	private final static String MOBILE_PATTERN = "^\\d{11}$";
	/**
	 * 校验统一社会信用代码
	 * @param companyCode
	 * @return 
	 */
	public static boolean checkCompanyCode(String companyCode){
        if(null!=companyCode && Pattern.matches(CONPANY_CODE_PATTERN, companyCode)){
            int sum =0;
            String[] idArray = companyCode.split("");
            for(int i=0;i<idArray.length-1;i++){
				sum+= COMPANY_WEIGHT[i] * COMPANY_CHAR_WEIGHT.get(idArray[i]);
            }
            return COMPANY_CHAR_WEIGHT.get(idArray[17]) + sum%31 ==31;
        }else{
            return false;
        }
    }
	/**
	 * 校验身份证
	 * @param idCardNo
	 * @return
	 */
	public static boolean checkIdCardNo(String idCardNo){
		if(null!=idCardNo && Pattern.matches(IDCARD_PATTERN, idCardNo)){
			int sum =0;
			String[] idArray = idCardNo.split("");
			for(int i=0;i<idArray.length-1;i++){
				sum+= IDCARD_WEIGHT[i] * Integer.parseInt(idArray[i]);
			}
			return IDCARD_CHECK_CODE[sum%11].equals(idArray[17]);
		}else{
			return false;
		}		
	}
	/**
	 * 校验车牌号
	 * @param regno
	 * @return
	 */
	public static boolean checkRegno(String regno){		
		return Pattern.matches(REGNO_PATTERN, String.valueOf(regno));
	}
	/**
	 * 校验美版VIN是否合法
	 * @param in
	 * @return
	 */
	public static boolean checkVin(String vin){
		if(null!=vin && Pattern.matches(VIN_PATTERN, vin)){
			int sum = 0;
			String[] vinA = vin.split("");
			for(int i=0;i<vinA.length;i++){
				sum+=VIN_CHAR_WEIGHT.get(vinA[i])*VIN_WEIGHT[i];
			}
			return vinA[8].equals(String.valueOf(sum%11)) || (vinA[8].equals("X") && sum%11==10);
		}else{
			return false;
		}
	}
	/**
	 * 校验手机号码是否符合规则
	 * @param mobile
	 * @return
	 */
	public static boolean checkMobile(String mobile){
		return null!=mobile && Pattern.matches(MOBILE_PATTERN, mobile);
	}
}
